/**
 * TypingAnimation - 正在输入动画组件
 *
 * 展示三个依次闪烁的圆点，模拟正在输入效果
 *
 * 特性：
 * - 基于 useFrameAnimationController 实现
 * - 支持自定义颜色、尺寸、透明度
 * - 支持外部控制播放/停止
 * - 循环播放
 *
 * @example
 * ```tsx
 * <TypingAnimation
 *   playing={isTyping}
 *   color="#999"
 *   size="medium"
 * />
 * ```
 */

import React, { useMemo, useEffect } from 'react';
import { View, Animated, Easing, StyleSheet } from 'react-native';
import { useFrameAnimationController } from '../../hooks/useFrameAnimationController';

/**
 * 组件属性
 */
export interface TypingAnimationProps {
  /** 是否播放，默认 false */
  playing?: boolean;

  /** 颜色，默认 '#999999' */
  color?: string;

  /** 预设尺寸，默认 'medium' */
  size?: 'small' | 'medium' | 'large';

  /** 自定义圆点大小（覆盖 size） */
  dotSize?: number;

  /** 自定义间距（覆盖 size） */
  gap?: number;

  /** 每帧持续时间（毫秒），默认 300 */
  frameDuration?: number;

  /** 亮起时的透明度，默认 1.0 */
  activeOpacity?: number;

  /** 暗淡时的透明度，默认 0.3 */
  inactiveOpacity?: number;
}

/**
 * 预设尺寸配置
 */
const SIZE_PRESETS = {
  small: { dotSize: 6, gap: 3 },
  medium: { dotSize: 8, gap: 4 },
  large: { dotSize: 10, gap: 5 },
};

/**
 * 正在输入动画组件
 */
export function TypingAnimation({
  playing = false,
  color = '#999999',
  size = 'medium',
  dotSize: customDotSize,
  gap: customGap,
  frameDuration = 300,
}: TypingAnimationProps) {
  // 1. 计算尺寸
  const preset = SIZE_PRESETS[size];
  const dotSize = customDotSize ?? preset.dotSize;
  const gap = customGap ?? preset.gap;

  // 3. 定义帧数据（归一化到 0-1）
  // 4帧动画：依次点亮每个圆点
  const frameData = useMemo(
    () => ({
      dot1Opacity: [0, 1, 0, 0],
      dot2Opacity: [0, 0, 1, 0],
      dot3Opacity: [0, 0, 0, 1],
    }),
    [],
  );

  // 2. 使用 Hook
  const {
    animatedValue,
    registerAnimation,
    interpolations,
    play,
    stop,
    isPlaying,
  } = useFrameAnimationController({ frameData, frameCount: 4 });

  // 4. 创建并注册对象
  useEffect(() => {
    // 创建循环动画
    const animation = Animated.loop(
      Animated.timing(animatedValue, {
        toValue: 3, // 4帧：0, 1, 2, 3
        duration: frameDuration * 4,
        easing: Easing.linear,
        useNativeDriver: true, // opacity 支持原生驱动
      }),
    );

    registerAnimation(animation);
  }, [frameDuration, animatedValue, registerAnimation]);

  // 5. 响应外部 playing prop
  useEffect(() => {
    if (playing && !isPlaying) {
      play();
    } else if (!playing && isPlaying) {
      stop();
    }
  }, [playing, isPlaying, play, stop]);

  // 6. 渲染
  if (!interpolations) {
    return null;
  }

  return (
    <View
      style={[
        styles.container,
        {
          gap,
        },
      ]}
    >
      <Animated.View
        style={{
          width: dotSize,
          height: dotSize,
          borderRadius: dotSize / 2,
          backgroundColor: color,
          opacity: interpolations.dot1Opacity,
        }}
      />
      <Animated.View
        style={{
          width: dotSize,
          height: dotSize,
          borderRadius: dotSize / 2,
          backgroundColor: color,
          opacity: interpolations.dot2Opacity,
        }}
      />
      <Animated.View
        style={{
          width: dotSize,
          height: dotSize,
          borderRadius: dotSize / 2,
          backgroundColor: color,
          opacity: interpolations.dot3Opacity,
        }}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    alignItems: 'center',
  },
});
